home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 19 / CU Amiga Magazine's Super CD-ROM 19 (1998)(EMAP Images)(GB)[!][issue 1998-02].iso / CUCD / Programming / LEDA / source / src / plane / _voronoi.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-16  |  2.2 KB  |  126 lines

  1. /*******************************************************************************
  2. +
  3. +  LEDA  3.1c
  4. +
  5. +
  6. +  _voronoi.c
  7. +
  8. +
  9. +  Copyright (c) 1994  by  Max-Planck-Institut fuer Informatik
  10. +  Im Stadtwald, 6600 Saarbruecken, FRG     
  11. +  All rights reserved.
  12. *******************************************************************************/
  13.  
  14.  
  15. #include <LEDA/voronoi.h>
  16. #include <LEDA/segment.h>
  17. #include <LEDA/impl/delaunay_tree.h>
  18. #include <LEDA/d_array.h>
  19.  
  20.  
  21.  
  22. static d_array<point,node>* VP;
  23.  
  24. static GRAPH<point,point>*  G;
  25.  
  26. static double infi_length;
  27.  
  28. static point* XP;
  29.  
  30.  
  31. static void trace_segment(double x1, double y1, double x2, double y2, 
  32.                    double sx0, double sy0)
  33. {
  34.   point p(x1,y1);
  35.   point q(x2,y2);
  36.   point s(sx0,sy0);
  37.  
  38.   node v,w;
  39.  
  40.   if ((v = (*VP)[p]) == nil) (*VP)[p] = v = G->new_node(p);
  41.     
  42.   if ((w = (*VP)[q]) == nil) (*VP)[q] = w = G->new_node(q);
  43.  
  44.   G->new_edge(v,w,s);
  45.  
  46.  
  47. }
  48.  
  49.  
  50. static void infi_point(double x1, double y1, double x2, double y2, double* x, double* y)
  51. {
  52.   vector v(x2,y2);
  53.  
  54.   v = v.norm();
  55.  
  56.   *x = x1 + infi_length * v[0];
  57.   *y = y1 + infi_length * v[1];
  58.  
  59. }
  60.  
  61.  
  62. static int cmp_infi_pts(const point& p, const point& q)
  63. { // used to sort infi points clockwise around XP
  64.   segment  s1(*XP,p);
  65.   segment  s2(*XP,q);
  66.   return compare(s2.angle(),s1.angle());
  67. }
  68.  
  69.  
  70. void VORONOI(list<point>& site_list, double R, GRAPH<point,point>& VD)
  71.    if (site_list.empty()) return;
  72.  
  73.    d_array<point,node> V(nil);
  74.  
  75.    point X = site_list.head();
  76.  
  77.    VP = &V;
  78.    XP = &X;
  79.  
  80.    delaunay_tree DT;
  81.  
  82.    point p,q;
  83.    node v;
  84.  
  85.    list<point> infi_list;
  86.  
  87.    forall(p,site_list) DT.insert(p,0);
  88.  
  89.    infi_length = R;
  90.  
  91.    G = &VD;
  92.  
  93.    DT.trace_voronoi_edges(trace_segment, infi_point, 1);
  94.  
  95.  
  96.    // sort & link infinite points
  97.  
  98.    forall_nodes(v,VD) 
  99.      if (VD.outdeg(v) == 1) infi_list.append(VD[v]);
  100.  
  101.    infi_list.sort(cmp_infi_pts);
  102.  
  103.    point INFI(MAXDOUBLE,MAXDOUBLE);  
  104.  
  105.    list_item it;
  106.  
  107.    forall_items(it,infi_list)
  108.    {  node p = V[infi_list[it]];
  109.       node q = V[infi_list[infi_list.cyclic_succ(it)]];
  110.       point s = VD[VD.first_adj_edge(q)];
  111.       VD.new_edge(p,q,s); 
  112.     }
  113.  
  114.    forall_items(it,infi_list)
  115.    {  node p = V[infi_list[it]];
  116.       node q = V[infi_list[infi_list.cyclic_pred(it)]];
  117.       VD.new_edge(p,q,INFI);  
  118.     }
  119.  
  120.    V.clear();
  121.  
  122. }
  123.  
  124.